﻿/*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Ajax类接口说明:

本类除了核心该去Get()和Post()之外，还封装有扩展方法enURL()、enHTML()、unHTML、enURL()、unURL()、Chk()等，其中扩展方法可以随便修改或自行增加扩展，不影响本类。
建议提交数据前先用enURI()方法转码数据;如果返回的数据是要插入到HTML代码中的建议插入前先用enHTML()方法转码

Get()方法的调用形式为：对象名.Get(URL, fnHandle[,Type]);
URL: 服务端地址(必选),向服务端发送的数据请在URL中以"URL?参数=要发送的数据"的形式添加;
fnHandle: 自定义的用于处理返回数据的函数句柄(必选),该自定义函数必须带有一个参数用于接收返回的数据,否则请自行从默认参数arguments[0]中提取返回的数据;
Type: 返回数据的类型(可选),值为'XML'返回XML数据,),值为'JSON'返回JSON数据，省略此参数或设为其它值则返回HTML数据。 增加JSON格式

Post()方法的调用形式为：对象名.Post(URL, Data, fnHandle[,Type]);
URL: 服务端地址(必选);
Data: 向服务端发送的表单数据(必选)，其值的格式必须为以下两种形式之一:
第一种普通的字串连接格式如: name=Someye&age=24 ;
第二种形式就是joson格式如：{name:"Someye",age:24} 
fnHandle: 自定义的用于处理返回数据的函数句柄(必选),该自定义函数必须带有一个参数用于接收返回的数据,否则请自行从默认参数arguments[0]中提取返回的数据;
Type: 返回数据的类型(可选),值为'XML'返回XML数据,省略此参数或设为其它值则返回HTML数据。

调用示例：
var Show = function(rData){  //定义要处理返回数据的函数句柄，其中rData或隐形参数arguments[0]为Ajax成功返回的数据
		alert("你要的数据是："+rData);  //请在这里自行处理返回的数据rData
	}
	
var obj = new AjaxClass();  //实例化对象
obj.Get("ajax.php?msg=fuckyou",Show, "XML");  //第三个参数'XML'表示返回XML数据，如果要返回HTML数据则省略该参数或改为除'XML'(包括大小写)之外的任意值即可 
obj.Post("ajax.php", Data, Show)  // Post方法缺省第四个参数默认返回HTML数据
*/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/*******************************************************************
 * 	@Description  : AjaxClass                                      *
 *	@FileName 	  : AjaxClass.js                                   *
 * 	@Author   	  : Someye                                         * 
 * 	@Date     	  : 2012-02-01                                     *
 * 	@Comment  	  : This is a Ajax Class                           *
 * 	@Method  	  : Get(); Post(); enURI(); enHTML(); unHTML();... *
 * 	@format Get   : obj.Get(URL, fnHandle[, Type]);                *
 * 	@format Post  : obj.Get(URL, Data, fnHandle[, Type]);          *
 * 	@format Chk   : obj.Chk(DataStr); Convert character            *
 * 	@example Post : obj.Post("do.php", Data, Show, 'XML');         *
 ******************************************************************/
function AjaxClass()
{	
	this.URL = "";
	this.ShowHandle = '';
	this.PostData = '';
	this.Type = '';
	this.XHR = this.Create() ;	

}


AjaxClass.prototype = 
{	
	//封装一个方法bine,其功能实现以obj身份调用obj的strFunc方法
	Bind:function(obj,strFunc){
		return function(){		//只是返回这个函数体，并未执行
		 	obj[strFunc].apply(obj); //以obj身份调用obj[strFunc]方法,这里用call方法代替apply方法也可以
		}
	},

	//创建XMLHttpRequest对象
	Create:function(){
		var xmlHttp = false;
		if(window.XMLHttpRequest){ //在非IE中创建XMLHttpRequest对象
			xmlHttp = new XMLHttpRequest();
		}else if(window.ActiveXObject){
			try{
				xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");	//高版本IE
			}catch(error1){//创建IP高版本XMLHttpRequest对象失败
				try{
					xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");  //低版本IE
				}catch(error2){ //创建IP低版本XMLHttpRequest对象失败
					xmlHttp = false;					
				}
			}
		}
		
		if(!xmlHttp){
			alert("创建XMLHttpRequest对象失败！程序无法运行，请检查您的浏览器类型与版本！");
			return false;	
		}
		return xmlHttp;
	},
	
	ResponseHandle:function(){
		if(this.XHR.readyState == 4 || this.XHR.readyState == "complete"){
			if(this.XHR.status == 200){
				if(this.Type == "XML"){
						this.ShowHandle(this.XHR.responseXML);
				}else if(this.Type == "JSON"){
						if(this.XHR.responseText == undefined || this.XHR.responseText == ''){  //没有数据返回。//为兼容FF，当没有数据返回时，设置返回数据为undefined
							this.ShowHandle(undefined); //没有数据返回时统一返回undefined给函数this.ShowHandle()
						}else{ //有数据返回
							this.ShowHandle(eval("("+this.XHR.responseText+")"));
						}
				}else{
						this.ShowHandle(this.XHR.responseText);
				}
			}		
		}	
	},

	//定义Get方法提交数据,参数TagetURL(必选)为服务端URL，参数fnHandle(必选)为自定义的处理结果函数句柄，rType(可选)为返回数据的类型
	Get:function(TagetURL, fnHandle, rType){ 
		  if(TagetURL != undefined && fnHandle != undefined ){
			  this.ShowHandle = fnHandle;	
			  if(TagetURL.indexOf('?') == -1){ //如果URL不含有问号字符则直接加?+时间戳，否则直接加&+时间戳
				  this.URL = TagetURL+"?"+(new Date()).valueOf();  //避免缓存添加时间戳
			  }else{
				  this.URL = TagetURL+"&"+(new Date()).valueOf();  //避免缓存添加时间戳	
			  }
		  }else{
			  alert("调用Get()方法错误，请填写正确的参数，帮助请阅读类接口说明");
		  }
		  if(rType != undefined){ 
			  this.Type = rType.toUpperCase();
		  }
		  if(window.XMLHttpRequest){
			  this.XHR.open("get",this.URL);
			  this.XHR.onreadystatechange = this.Bind(this,"ResponseHandle"); //绑定this.XHR的onreadystatechange事件到ResponseHandle方法中.，并传参数this		
			  this.XHR.send(null);	
		  }else{
			  this.XHR.open("get", this.URL, true);
			  this.XHR.onreadystatechange = this.Bind(this,"ResponseHandle"); //绑定this.XHR的onreadystatechange事件到ResponseHandle.，并传参数this
			  this.XHR.send();
		  }
	},
	
	//定义Post方法提交数据,参数TagetURL(必选)为服务端URL，Data为提交的数据，参数fnHandle(必选)为自定义的处理结果函数句柄，rType(可选)为返回数据的类型
	Post:function(TagetURL, Data, fnHandle, rType){
		  if(TagetURL != undefined && Data != undefined && fnHandle != undefined ){
			  this.ShowHandle = fnHandle;	
			  this.URL = TagetURL;
		  }else{
			  alert("调用Get()方法错误，请填写正确的参数，帮助请阅读类接口说明");
		  }
		  if(rType != undefined){
			  this.Type = rType.toUpperCase();
		  }	
		
		if(typeof(Data) == "object"){ //如果是joson形式的对象数据则转转成普通的字符串连接形式
			var Dstr=""; 
			for(var d in Data){
				Dstr += d+"="+Data[d]+"&"; 
			} 
			this.PostData = Dstr.substr(0, Dstr.length-1); 
		}else{ 
			this.PostData = Data;  //普通的字符串连接形式,如:name=someye&age=24
		} 

		this.XHR.open("post", TagetURL, true); 
		this.XHR.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); 
		this.XHR.onreadystatechange = this.Bind(this,"ResponseHandle"); //绑定this.XHR的onreadystatechange事件到ResponseHandle方法中.，并传参数this
		this.XHR.send(this.PostData); 
	},
	
/*********************************************************************************
   下面是自定义封装的方法，在本Ajax类的实现中用不到，可以随便修改或自行扩展自己的方法
/*********************************************************************************/	
	
	//封装一个URI编码，推荐提交数据前使用这个方法对数据进行编码
	enURI:function(DataStr){
		return encodeURIComponent(DataStr);	
	},
			
	//封装一个HTMLencode编码方法
	enHTML:function(DataStr) {
		 var Str = DataStr;
		 Str = Str.replace(/\&/g, "&amp;");
		 Str = Str.replace(/\</g, "&lt;");
		 Str = Str.replace(/\>/g, "&gt;");  
		 Str = Str.replace(/\'/g, "&#39;");
		 Str = Str.replace(/\"/g, "&quot;");
	 	 return Str;
	},
	//封装一个HTMLencode解码方法
	unHTML:function(DataStr){
		var Str = DataStr;   
		Str = Str.replace(/&amp;/g, "&");
		Str = Str.replace(/&lt;/g, "<");
		Str = Str.replace(/&gt;/g, ">"); 
		Str = Str.replace(/&#39;/g, "\'");   
		Str = Str.replace(/&quot;/g, "\""); 
		return Str;   
	},	
	
	//下面这个方法只转换+号和&号
	Chk:function(DataStr){
			var	Str = DataStr;
			Str = Str.replace(/\+/g, "%2B"); //先转换+号
			Str = Str.replace(/\&/g, "%26"); //再转换&号
			return Str;
	},
		
	//封装一个编码方法用于对提交的数据编码，如有需要请在提交数据前调用
	enURL:function(DataStr){ //不推荐使用本方法
		var	Str = DataStr;
		Str = DataStr.replace(/\+/g, "%2B"); //先转换+号
		Str = escape(Str);  //最后全部编码为url
		return Str;
	},
	//封装一个解码的方法，如果调用的前面的编码方法输出数据前必须调用该解码方法
	unURL:function(DataStr){
		return unescape(DataStr);
	}
				
}
